﻿using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TaskManageDemo.Data;
using TaskManageDemo.Data.Entitys;
using TaskManageDemo.Utility;

namespace TaskManageDemo.Core
{
    /// <summary>
    /// 作业计划基类
    /// </summary>
    public abstract class JobBase : IJob
    {
        private readonly IRepository _scheduleTask;
        public JobBase()
        {
            this._scheduleTask = new Repository();
        }

        public void Execute(IJobExecutionContext context)
        {
            //Quartz.Collection.ISet<JobKey> jobKeys = context.Scheduler.GetJobKeys(
            //      Quartz.Impl.Matchers.GroupMatcher<JobKey>.GroupEquals(JobHelp.jobGroupName));    //取所有运行的作业

            var task = context.MergedJobDataMap["task"] as ScheduleTask;
            string message = string.Format("{0}的『Execute』从『IJobExecutionContext』读取不到作业计划！", ""); // this.FullDevName
            if (task == null) throw new Exception(message);

            //刷新作业计划信息，防止作业计划配置发生改变
            string sql = "select * from ScheduleTask where id=@id";
            var taskNew = _scheduleTask.GetFirst<ScheduleTask>(sql, new { id = task.Id });

            if (taskNew == null)
            {
                //计划已经被删除，则删除此作业
                context.Scheduler.DeleteJob(context.JobDetail.Key);
                Log.Logger.InfoFormat(string.Format("{0}作业计划为空，该记录可能已经被删除。", taskNew.ClassName));
                return; //退出
            }

            //作业不允许使用
            if (!taskNew.Allowused)
            {
                //不从调度计划中删除本作业，因为有可能又启用该作业计划
                Log.Logger.InfoFormat(string.Format("{0}作业计划不允许使用，跳过此次执行。", taskNew.ClassName));
                return; //退出
            }
            if (taskNew != task)
            {

                //脏数据，删除此作业，然后重新创建一个
                Log.Logger.InfoFormat("{0}的作业计划属性已更改，将删除该计划的实现作业，然后重新创建一个作业，并尝试调度它...", taskNew.ClassName);
                //作业计划属性发生变更，重新启动作业
                Tuple<IJobDetail, ITrigger> tuple = JobHelp.RestartJob(context.Scheduler, task, taskNew);
                Log.Logger.InfoFormat("{0}重新创建并调度作业完成，『IJOB.Execute』退出。作业计划：{1}，作业：{2}，触发器：{3}，表达式：{4}。", taskNew.ClassName, taskNew.ClassName, tuple.Item1.Key.Name, tuple.Item2.Key.Name, taskNew.CronExpression);
                return; //退出
            }
            
            //执行具体作业的业务逻辑
            ExecuteJobImpl(context);

            //更新执行时间
            taskNew.LastTime=DateTime.Now.ToString();
            taskNew.NextTime = string.Format("{0:G}", context.NextFireTimeUtc.Value.AddHours(8));
            UpdateTime(taskNew);
        }

        protected abstract void ExecuteJobImpl(IJobExecutionContext context);

        protected void UpdateTime(ScheduleTask task)
        {
           TaskManageDemo.Utility.Common.Execute(_scheduleTask.Update<ScheduleTask>,task,"更新时间出错");
        }

    }
}
